package org.fuys.coder.domain.auth.service.handler.register.impl;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.fuys.coder.common.constants.FileConstants;
import org.fuys.coder.common.constants.RedisConstants;
import org.fuys.coder.common.constants.ResultMessageConstants;
import org.fuys.coder.common.exception.BusinessException;
import org.fuys.coder.domain.auth.repository.ICaptchaRepository;
import org.fuys.coder.infrastructure.util.RedisUtil;
import org.fuys.coder.domain.audit.model.req.AuditTask;
import org.fuys.coder.domain.audit.model.res.AuditResult;
import org.fuys.coder.domain.audit.model.vo.AuditResultTypeVO;
import org.fuys.coder.domain.audit.model.vo.AuditTaskTypeVO;
import org.fuys.coder.domain.audit.service.Audit;
import org.fuys.coder.infrastructure.model.dto.UserDTO;
import org.fuys.coder.domain.auth.model.res.AuthFailedEnum;
import org.fuys.coder.domain.auth.service.handler.register.RegisterHandler;
import org.fuys.coder.domain.signup.service.point.Policy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @projectName: fuys-low-coder
 * @package: org.fuys.coder.domain.auth.service.handler.register.impl
 * @className: BeforeSaveHandler
 * @author: WangJing
 * @description: 在创建用户之前需要执行的一些操作
 * @date: 2024/6/20 16:34
 * @version: 1.0
 */
@Service
public class BeforeSaveHandler implements RegisterHandler {

    @Resource
    private ICaptchaRepository captchaRepository;

    @Resource(name="addPoint")
    private Policy addPoint;

    @Resource
    private Audit audit;

    @Override
    public boolean handle(UserDTO userDTO) throws BusinessException {
        //为了防止前端被篡改 如像PostMan一样 直接给一个不可用的邮箱 如果还像正常一样处理 那就完犊子了
        //因此 这一层要在真正注册之前 进行校验 校验的方式是检查Redis 中是否存在此邮箱的信息 在这一层中进行删除
        //因为校验也确实是需要在Save之前进行 所以逻辑上应该没有问题？
        AuditTask auditTask=new AuditTask();
        auditTask.setType(AuditTaskTypeVO.TEXT.getIndex());
        auditTask.setNeedResultHandle(false);
        auditTask.setTasks(new String[]{userDTO.getUsername()});
        final AuditResult auditResult = audit.doAudit(auditTask);
        if(auditResult.isFinish()){
            if(!(auditResult.getType()== AuditResultTypeVO.PASS.getIndex())){
                return false;
            }
        }else{
            throw new BusinessException(ResultMessageConstants.AUDIT_TEXT_FAILED+":用户名异常");
        }
        final String key = RedisConstants.REDIS_FIELD_EMAIL + userDTO.getEmail();
        final Object o = captchaRepository.getCaptcha(key);
        //如果发现邮箱验证码是空 则需要抛出业务异常
        if(ObjectUtils.isEmpty(o)){
            throw new BusinessException(AuthFailedEnum.EMAIL_CODE_EXPIRED.getMsg());
        }else if(!((o.toString()).equals(userDTO.getCode()))){
            throw new BusinessException(AuthFailedEnum.EMAIL_CODE_MISMATCH.getMsg());
        }
        captchaRepository.deleteCaptcha(key);
        userDTO.setAvatar(FileConstants.DEFAULT_AVATAR_ID);
        //否则 开始为其增加积分
        try {
            addPoint.execute(userDTO,50);
        } catch (Exception e) {
            //如果出现了异常 为了不影响之后的运行 这里给出默认的处理逻辑
            userDTO.setPoint(50);
        }
        return true;
    }
}
